home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / Font.C < prev    next >
C/C++ Source or Header  |  1992-04-27  |  8KB  |  389 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Font.h"
  6.  
  7. #include "Class.h"
  8. #include "Error.h"
  9. #include "String.h"
  10. #include "WindowSystem.h"
  11. #include "ObjArray.h"
  12. #include "OrdColl.h"
  13. #include "Env.h"
  14. #include "Math.h"
  15.  
  16. Font *gSysFont,
  17.      *gApplFont,
  18.      *gFixedFont;
  19.        
  20. class FontManager *gFontManager;
  21. bool freal;
  22.  
  23. static Symbol FontNames[12];
  24.  
  25. //---- Font --------------------------------------------------------------------
  26.  
  27. NewMetaImpl(Font,Object, (TA(cw), TE(face), T(size), T(ils), T(ht), T(bs), T(width), TP(ff)));
  28.  
  29. Font *new_Font(GrFont font, int size, GrFace face)
  30.     return gFontManager->MapFont(font, size, face);
  31. }
  32.  
  33. Font *new_Font(GrFont font, int size, GrFace face, bool)
  34. {
  35.     freal= TRUE;
  36.     Font *fp= gFontManager->MapFont(font, size, face);
  37.     freal= FALSE;
  38.     return fp;
  39. }
  40.  
  41. Font::Font(FontFamily *f, short ps, GrFace fc)
  42. {
  43.     ff= f;
  44.     size= ps;
  45.     face= fc;
  46.     if (ff)
  47.     ff->fmap->Add(this);
  48. }
  49.  
  50. Font *Font::WithFace(GrFace fc)
  51. {
  52.     return gFontManager->MapFont(Fid(), size, fc);
  53. }
  54.  
  55. Font *Font::WithSize(int sz)
  56. {
  57.     return gFontManager->MapFont(Fid(), sz, face);
  58. }
  59.  
  60. int Font::Width(register byte *s, register int l)
  61. {
  62.     register int w= 0;
  63.     
  64.     if (s) {
  65.     if (l < 0) {
  66.         while(*s)
  67.         w+= cw[*s++];
  68.     } else {
  69.         while(--l >= 0)
  70.         w+= cw[*s++];
  71.     }
  72.     }
  73.     return w;
  74. }
  75.  
  76. int Font::MaxWidth(int l)
  77. {
  78.     if (width < 0) {
  79.     register int i;
  80.     
  81.     width= 0;
  82.     for (i= 0; i< 255; i++)
  83.         width= Math::Max((u_short)width, cw[i]);
  84.     }
  85.     return l*width;
  86. }
  87.  
  88. Rectangle Font::BBox(register byte *s, register int l)
  89. {
  90.     register int w= 0;
  91.     
  92.     if (s == 0)
  93.     return gRect0;
  94.     if (l < 0) {
  95.     while(*s)
  96.         w+= cw[*s++];
  97.     } else {
  98.     while(--l >= 0)
  99.         w+= cw[*s++];
  100.     }
  101.     return Rectangle(0, ht, w, ht+bs);
  102. }
  103.  
  104. Metric Font::GetMetric(register byte *s, register int l)
  105. {
  106.     register int w= 0;
  107.     
  108.     if (s == 0)
  109.     return Metric(0);
  110.     if (l < 0) {
  111.     while(*s)
  112.         w+= cw[*s++];
  113.     } else {
  114.     while(--l >= 0)
  115.         w+= cw[*s++];
  116.     }
  117.     return Metric(w, Ascender()+Descender(), Ascender());
  118. }
  119.  
  120. Metric Font::GetMetric(byte c)
  121. {
  122.     return Metric(Width(c), Ascender()+Descender(), Ascender());
  123. }
  124.  
  125. Rectangle Font::BBox(register byte c, Point pos)
  126. {
  127.     return Rectangle(pos.x, pos.y-Ascender(), Width(c), Spacing());
  128. }
  129.  
  130. Point Font::AdjustString(register byte *s, Point p, GrVAdjust va, GrHAdjust ha)
  131. {
  132.     register int w= 0;
  133.     
  134.     if (ha) {
  135.     if (s)
  136.         while(*s)
  137.         w+= cw[*s++];
  138.     
  139.     switch (ha) {
  140.     case eAdjHRight:
  141.         p.x-= w;
  142.         break;
  143.     case eAdjHCenter:
  144.         p.x-= w/2;
  145.         break;
  146.     default:
  147.         break;
  148.     }
  149.     }
  150.     switch (va) {
  151.     case eAdjVBottom:
  152.     p.y-= bs;
  153.     break;
  154.     case eAdjVCenter:
  155.     p.y+= (ht-bs)/2;
  156.     break;
  157.     case eAdjVTop:
  158.     p.y+= ht;
  159.     break;
  160.     case eAdjVBase:
  161.     break;
  162.     }
  163.     return p;
  164. }
  165.  
  166. DevBitmap *Font::CharAsBitmap(byte, Point*)
  167. {
  168.     return 0;
  169. }
  170.  
  171. char *Font::AsString()
  172. {
  173.     return form("%s.%d.%s", Name(), Size(), gFontManager->StyleString(Face()));
  174. }
  175.  
  176. u_long Font::Hash()
  177. {
  178.     return (u_long) Fid();
  179. }
  180.  
  181. bool Font::IsEqual(Object *op)
  182. {
  183.     return op->IsKindOf(Font) && ((Font*)op)->Size() == Size()
  184.                         && ((Font*)op)->Face() == Face();
  185. }
  186.  
  187. OStream& Font::PrintOn(OStream &s)
  188. {
  189.     return s << FontNames[Fid()] SP << Size() SP << (int)Face() SP;
  190. }
  191.  
  192. Object *Font::ReadAndMap(IStream &s)
  193. {
  194.     int size;
  195.     GrFace face;
  196.     Symbol name;
  197.     s >> name >> size >> Enum(face);
  198.     return new_Font(gFontManager->NameToId(name.AsString()), size, face);
  199. }
  200.  
  201. //---- FontManager -------------------------------------------------------------
  202.  
  203. NewMetaImpl(FontManager,Object, (TP(fmap)));
  204.  
  205. FontManager::FontManager()
  206. {
  207.     fmap= new ObjArray;
  208.     
  209.     FontNames[0]= Symbol("Times");
  210.     FontNames[1]= Symbol("Helvetica");
  211.     FontNames[2]= Symbol("Courier");
  212.     FontNames[3]= Symbol("Symbol");
  213.     FontNames[4]= Symbol("Chicago");
  214.     FontNames[5]= Symbol("Avantgarde");
  215.     FontNames[6]= Symbol("Bookman");
  216.     FontNames[7]= Symbol("Schoolbook");
  217.     FontNames[8]= Symbol("NarrowHelvetica");
  218.     FontNames[9]= Symbol("Palatino");
  219.     FontNames[10]= Symbol("ZapfChancery");
  220.     FontNames[11]= Symbol("ZapfDingbats");
  221. }
  222.  
  223. FontManager::~FontManager()
  224. {
  225.     if (fmap) {
  226.     fmap->FreeAll();
  227.     SafeDelete(fmap);
  228.     }
  229. }
  230.  
  231. bool FontManager::Init()
  232. {
  233.     int size= Env::GetValue("Font.Size", 12);
  234.     GrFont fid= gFontManager->NameToId(Env::GetValue("Font.Sys", "Chicago"));
  235.     gSysFont= new_Font(fid, size);
  236.     fid= gFontManager->NameToId(Env::GetValue("Font.Appl", "Helvetica"));
  237.     gApplFont= new_Font(fid, size);
  238.     fid= gFontManager->NameToId(Env::GetValue("Font.Fixed", "Courier"));
  239.     gFixedFont= new_Font(fid, size);
  240.     return FALSE;
  241. }
  242.  
  243. FontFamily *FontManager::MapFamily(GrFont fid)
  244. {
  245.     FontFamily *fm;
  246.     
  247.     if ((fm= (FontFamily*) fmap->At(fid)) == 0) {
  248.     if (fid < eFontTimes || fid > eFontDingbats)
  249.         return (FontFamily*) fmap->At(eFontChicago);
  250.     fmap->AtPutAndExpand(fid, fm= new FontFamily(fid));
  251.     }
  252.     return fm;
  253. }
  254.     
  255. Font *FontManager::MapFont(GrFont fid, int size, GrFace face)
  256. {
  257.     return MapFamily(fid)->MapSizeFace(size, face);
  258. }
  259.  
  260. Font *FontManager::MakeFont(FontFamily*, int, GrFace, bool)
  261. {
  262.     return 0;
  263. }
  264.     
  265. Font *FontManager::ScaleFont(FontFamily *ff, int size, GrFace face)
  266. {
  267.     Font *f;
  268.     int facebit;
  269.  
  270.     if (face != eFacePlain) {
  271.     for (facebit= eFaceShadow; facebit; facebit >>= 1) {
  272.         if (face & facebit) {
  273.         face= (GrFace) (face & ~facebit);
  274.         return ff->MapSizeFace(size, face);
  275.         }
  276.     }
  277.     }
  278.     for (int i= 6; i < 24; i++) {
  279.     if ((size-i > 6) && (f= ff->MapSizeFace2(size-i, face)))
  280.         return f;
  281.     if ((size+i > 24) && (f= ff->MapSizeFace2(size+i, face)))
  282.         return f;
  283.     }
  284.     return 0;
  285. }
  286.  
  287. GrFont FontManager::NameToId(char *fontname)
  288. {
  289.     Symbol name(fontname);
  290.     for (int i= 0; i < sizeof(FontNames) / sizeof(FontNames[0]); i++)
  291.     if (FontNames[i] == name)
  292.         return (GrFont)i;
  293.     return (GrFont)-1;
  294. }
  295.  
  296. char *FontManager::IdToName(GrFont fid)
  297. {
  298.     if (fid >= 0 && fid < sizeof(FontNames) / sizeof(FontNames[0]))
  299.     return FontNames[fid].AsString();
  300.     return 0;
  301. }
  302.  
  303. char *FontManager::StyleString(GrFace face)
  304. {
  305.     static char buf[20];
  306.     char *cp= buf;
  307.     if (face == eFacePlain)
  308.     *cp++= 'r';
  309.     else {
  310.     if (face & eFaceBold)
  311.         *cp++= 'b';
  312.     if (face & eFaceItalic)
  313.         *cp++= 'i';
  314.     if (face & eFaceUnderline)
  315.         *cp++= 'u';
  316.     if (face & eFaceOutline)
  317.         *cp++= 'o';
  318.     if (face & eFaceShadow)
  319.         *cp++= 's';
  320.     }
  321.     *cp= '\0';
  322.     return buf;
  323. }
  324.  
  325. void FontManager::CollectParts(class Collection *col)
  326. {
  327.     col->Add(fmap);
  328. }
  329.  
  330. //---- FontFamily --------------------------------------------------------------
  331.  
  332. NewMetaImpl(FontFamily,Object, (TE(fid), TB(fixed), TP(fmap)));
  333.  
  334. FontFamily::FontFamily(GrFont f)
  335. {
  336.     fid= f;
  337.     fmap= new OrdCollection;
  338. }
  339.  
  340. FontFamily::~FontFamily()
  341. {
  342.     if (fmap) {
  343.     fmap->FreeAll();
  344.     SafeDelete(fmap);
  345.     }
  346. }
  347.  
  348. char *FontFamily::Name()
  349. {
  350.     return FontNames[fid].AsString();
  351. }
  352.  
  353. Font *FontFamily::MapSizeFace2(int size, GrFace face, bool dflt)
  354. {
  355.     Iter next(fmap);
  356.     register Font *fp;
  357.     
  358.     // if (! freal) {
  359.     while (fp= (Font*) next())
  360.     if (fp->Size() == size && fp->Face() == face)
  361.         return fp;
  362.     // }
  363.     freal= FALSE;
  364.     return gFontManager->MakeFont(this, size, face, dflt);
  365. }
  366.  
  367. Font *FontFamily::MapSizeFace(int size, GrFace face)
  368. {
  369.     Font *f;
  370.     
  371.     if (f= MapSizeFace2(size, face))
  372.     return f;
  373.     if (f= gFontManager->ScaleFont(this, size, face))
  374.     return f;
  375.     return MapSizeFace2(0, face, TRUE);
  376. }
  377.  
  378. void FontFamily::InspectorId(char *buf, int bufSize)
  379. {
  380.     strncpy(buf, Name(), bufSize);
  381. }
  382.  
  383. void FontFamily::CollectParts(class Collection *col)
  384. {
  385.     col->Add(fmap);
  386. }
  387.  
  388.